package topuc.com.mvp.utils;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Rect;
import android.os.Build;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.LinearLayout;

/**
 * 控制底部各个功能块的工具类
 * Created by apls on 2018/11/26.
 */
public class EmotionKeyboard {

    private static final String SHARE_PREFERENCE_NAME = "EmotionKeyboard";
    private static final String SHARE_PREFERENCE_SOFT_INPUT_HEIGHT = "soft_input_height";

    private View mContentView;//内容布局
    private EditText mEditText;
    private View mEmotionView;//表情布局
    private InputMethodManager mInputManager;
    private Activity activity;
    private SharedPreferences sp;

    public static EmotionKeyboard with(Activity activity) {

        EmotionKeyboard emotionKeyboard = new EmotionKeyboard();
        emotionKeyboard.activity = activity;
        emotionKeyboard.mInputManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
        emotionKeyboard.sp=activity.getSharedPreferences(SHARE_PREFERENCE_NAME,Context.MODE_PRIVATE);

        return emotionKeyboard;
    }

    /**
     * 绑定内容布局
     *
     * @param contentView
     * @return
     */
    public EmotionKeyboard bindToContent(View contentView) {

        mContentView = contentView;
        return this;
    }

    /**
     * 绑定EditText
     *
     * @param editText
     * @return
     */
    public EmotionKeyboard bindEditText(EditText editText) {

        mEditText = editText;
        mEditText.requestFocus();
        mEditText.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {

                /**
                 * 触发touch事件
                 * (1)up事件
                 * (2)表情布局是否显示，如果显示则隐藏
                 * (3)都成立时显示软键盘
                 */
                if (motionEvent.getAction() == MotionEvent.ACTION_UP && mEmotionView.isShown()) {

                    //锁定mContentView的高度
                    lockContentHeight();
                    //隐藏mEmotionView的布局
                    mEmotionView.setVisibility(View.GONE);
                    //显示软键盘
                    mEditText.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            unlockDisplayDelayed();
                        }
                    }, 200L);
                }
                return false;
            }

        });

        return this;
    }

    /**
     * 绑定表情显示按钮
     * @param emotionButton
     * @return
     */
    public EmotionKeyboard bindToEmotionButton(View emotionButton) {

        emotionButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                if (mEmotionView.isShown()) {
                    lockContentHeight();
                    hideEmotionLayout(true);//隐藏表情布局并且显示软键盘
                    unlockDisplayDelayed();
                } else {
                    if (isSoftInputShow()) {
                        lockContentHeight();
                        showEmotionLayout();
                        unlockDisplayDelayed();
                    }else{
                        showEmotionLayout();
                    }
                }
            }
        });

        return this;
    }

    /**
     * 设置表情布局
     *
     * @param emotionView
     * @return
     */
    public EmotionKeyboard setEmotionView(View emotionView) {

        mEmotionView = emotionView;
        return this;
    }

    /**
     * 锁定上部分内容布局的高度
     */
    public EmotionKeyboard lockContentHeight() {

        LinearLayout.LayoutParams viewParams = (LinearLayout.LayoutParams) mContentView.getLayoutParams();
        viewParams.height = mContentView.getHeight();
        viewParams.weight = 0.0F;

        return this;
    }

    /**
     * 隐藏表情布局
     *
     * @param showSoftInput:是否显示软键盘 true：显示，false:不显示
     */
    public void hideEmotionLayout(boolean showSoftInput) {

        if (mEmotionView.isShown()) {
            mEmotionView.setVisibility(View.GONE);
            if (showSoftInput) {
                showSoftInput();
            }
        }
    }

    /**
     * 显示表情布局
     */
    public void showEmotionLayout(){

        int inputSoftHeight=getSoftButtonBarHeight();
        if(inputSoftHeight<=0){
            inputSoftHeight=getKeyboardHeight();
        }
        hideSoftInput();
        mEmotionView.getLayoutParams().height=inputSoftHeight;
        mEmotionView.setVisibility(View.VISIBLE);
    }

    /**
     * 显示软键盘
     */
    public void showSoftInput() {
        if (mInputManager != null) {
            mEditText.requestFocus();
            mInputManager.showSoftInput(mEditText, 0);
        }
    }

    /**
     * 隐藏软键盘
     */
    public void hideSoftInput(){

        if(mInputManager!=null){
            mInputManager.hideSoftInputFromWindow(mEditText.getWindowToken(),0);
        }
    }

    /**
     * 对上部分的布局解除锁定
     */
    public void unlockDisplayDelayed() {

        mEditText.postDelayed(new Runnable() {
            @Override
            public void run() {

                ((LinearLayout.LayoutParams) mContentView.getLayoutParams()).weight = 1.0F;
            }
        }, 200L);
    }

    /**
     * 当前软键盘是否显示
     */
    public boolean isSoftInputShow() {

        return getSoftInputHeight()!=0;
    }

    /**
     * 获取软键盘的高度
     *
     * @return
     */
    public int getSoftInputHeight() {

        Rect rect = new Rect();
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
        int inputSoftHeight = DisplayUtils.getScreenHeightPixels(activity) - rect.bottom;
        /**
         * 某些Android版本下，没有显示软键盘时减出来的高度总是144，而不是零，
         * 这是因为高度是包括了虚拟按键栏的(例如华为系列)，所以在API Level高于20时，
         * 我们需要减去底部虚拟按键栏的高度（如果有的话）
         */
        if (Build.VERSION.SDK_INT >= 20) {
            inputSoftHeight = inputSoftHeight - getSoftButtonBarHeight();
        }

        if(inputSoftHeight<0){
            Log.d("EmotionKeyboard","EmotionKeyboard--Warning: value of softInputHeight is below zero!");
        }

        if(inputSoftHeight>0){
            sp.edit().putInt(SHARE_PREFERENCE_SOFT_INPUT_HEIGHT,inputSoftHeight).apply();
        }

        return inputSoftHeight;
    }

    /**
     * 获取底部虚拟键盘的高度
     *
     * @return
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    public int getSoftButtonBarHeight() {

        DisplayMetrics displayMetrics = new DisplayMetrics();
        //此方法获取的可能不是屏幕真实的高度
        activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        int usableHeight = displayMetrics.heightPixels;
        activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        int realHeight = displayMetrics.heightPixels;

        if (realHeight > usableHeight) {
            return realHeight - usableHeight;
        } else {
            return 0;
        }
    }

    /**
     * 获取软键盘高度，由于第一次直接弹出表情时会出现小问题，787是一个均值，作为临时解决方案
     * @return
     */
    public int getKeyboardHeight(){

        return sp.getInt(SHARE_PREFERENCE_SOFT_INPUT_HEIGHT,787);
    }

    public EmotionKeyboard build(){
        //设置软件盘的模式：SOFT_INPUT_ADJUST_RESIZE  这个属性表示Activity的主窗口总是会被调整大小，从而保证软键盘显示空间。
        //从而方便我们计算软件盘的高度
        activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN|WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
        hideSoftInput();
        return this;
    }

}
